/**
 * Copyright 2021 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied。
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup MindSpore
 * @{
 * 
 * @brief 提供MindSpore Lite的模型推理相关接口。
 * 
 * @Syscap SystemCapability.Ai.MindSpore
 * @since 9
 */

/**
 * @file tensor.h
 * 
 * @brief 提供了张量相关的接口，可用于创建和修改张量信息。
 * 
 * @since 9
 */

#ifndef MINDSPORE_INCLUDE_C_API_TENSOE_C_H
#define MINDSPORE_INCLUDE_C_API_TENSOE_C_H

#include <stddef.h>
#include "mindspore/types.h"
#include "mindspore/data_type.h"
#include "mindspore/format.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 指向张量对象句柄
 * 
 * @since 9
 */
typedef void *OH_AI_TensorHandle;

/**
 * \brief 创建一个张量对象。
 *
 * \param name 张量名称
 * \param type 张量的数据类型
 * \param shape 张量的维度数组。
 * \param shape_num 张量维度数组长度。
 * \param data 指向数据的指针。
 * \param data_len 数据的长度。
 *
 * \return 指向张量对象句柄。
 * 
 * @since 9
 */
OH_AI_API OH_AI_TensorHandle OH_AI_TensorCreate(const char *name, OH_AI_DataType type, const int64_t *shape,
                                                size_t shape_num, const void *data, size_t data_len);

/**
 * \brief 释放张量对象。
 *
 * \param tensor 指向张量句柄的二级指针。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorDestroy(OH_AI_TensorHandle *tensor);

/**
 * \brief 深拷贝一个张量。
 *
 * \param tensor 待拷贝张量的指针。
 *
 * \return 指向新张量对象句柄。
 * 
 * @since 9
 */
OH_AI_API OH_AI_TensorHandle OH_AI_TensorClone(OH_AI_TensorHandle tensor);

/**
 * \brief 设置张量的名称。
 *
 * \param tensor 张量对象句柄。
 * \param name 张量名称。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorSetName(OH_AI_TensorHandle tensor, const char *name);

/**
 * \brief 获取张量的名称。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量的名称。
 * 
 * @since 9
 */
OH_AI_API const char *OH_AI_TensorGetName(const OH_AI_TensorHandle tensor);

/**
 * \brief 设置张量的数据类型。
 *
 * \param tensor 张量对象句柄。
 * \param type 数据类型，具体见{@link OH_AI_DataType}。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorSetDataType(OH_AI_TensorHandle tensor, OH_AI_DataType type);

/**
 * \brief 获取张量类型。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量的数据类型。
 * 
 * @since 9
 */
OH_AI_API OH_AI_DataType OH_AI_TensorGetDataType(const OH_AI_TensorHandle tensor);

/**
 * \brief 设置张量的形状。
 *
 * \param tensor 张量对象句柄。
 * \param shape 形状数组。
 * \param shape_num 张量形状数组长度。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorSetShape(OH_AI_TensorHandle tensor, const int64_t *shape, size_t shape_num);

/**
 * \brief 获取张量的形状。
 *
 * \param tensor 张量对象句柄。
 * \param shape_num 该参数是输出参数，形状数组的长度会写入该变量。
 *
 * \return 形状数组。
 * 
 * @since 9
 */
OH_AI_API const int64_t *OH_AI_TensorGetShape(const OH_AI_TensorHandle tensor, size_t *shape_num);

/**
 * \brief 设置张量数据的排列方式。
 *
 * \param tensor 张量对象句柄。
 * \param format 张量数据排列方式。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorSetFormat(OH_AI_TensorHandle tensor, OH_AI_Format format);

/**
 * \brief 获取张量数据的排列方式。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量数据的排列方式。
 * 
 * @since 9
 */
OH_AI_API OH_AI_Format OH_AI_TensorGetFormat(const OH_AI_TensorHandle tensor);

/**
 * \brief 设置张量的数据。
 *
 * \param tensor 张量对象句柄。
 * \param data 指向数据的指针。
 * 
 * @since 9
 */
OH_AI_API void OH_AI_TensorSetData(OH_AI_TensorHandle tensor, void *data);

/**
 * \brief 获取张量数据的指针。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量数据的指针。
 * 
 * @since 9
 */
OH_AI_API const void *OH_AI_TensorGetData(const OH_AI_TensorHandle tensor);

/**
 * \brief 获取可变的张量数据指针。如果数据为空则会开辟内存。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量数据的指针。
 * 
 * @since 9
 */
OH_AI_API void *OH_AI_TensorGetMutableData(const OH_AI_TensorHandle tensor);

/**
 * \brief 获取张量元素数量。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量的元素数量。
 * 
 * @since 9
 */
OH_AI_API int64_t OH_AI_TensorGetElementNum(const OH_AI_TensorHandle tensor);

/**
 * \brief 获取张量中的数据的字节数大小。
 *
 * \param tensor 张量对象句柄。
 *
 * \return 张量数据的字节数大小。
 * 
 * @since 9
 */
OH_AI_API size_t OH_AI_TensorGetDataSize(const OH_AI_TensorHandle tensor);

/**
 * \brief 设置张量为用户自行管理的数据。此接口常用于复用用户数据作为模型输入，可减少一次数据拷贝。
 * 注意：此数据对于张量来说是外部数据，张量销毁时不会主动释放，由调用者负责释放。另外，在此张量
 * 使用过程中，调用者须确保此数据有效。
 *
 * \param tensor 张量对象句柄。
 * \param data 用户数据首地址。
 * \param data_size 用户数据长度。
 *
 * \return 执行状态码。若成功返回OH_AI_STATUS_SUCCESS，否则返回具体错误码。
 *
 * @since 10
 */
OH_AI_API OH_AI_Status OH_AI_TensorSetUserData(OH_AI_TensorHandle tensor, void *data, size_t data_size);

#ifdef __cplusplus
}
#endif

/** @} */
#endif  // MINDSPORE_INCLUDE_C_API_TENSOE_C_H
